package com.zkthink.ceres.product.controller;

import com.zkthink.base.request.PageParams;
import com.zkthink.ceres.common.enums.YesOrNoEnum;
import com.zkthink.ceres.product.dto.SubjectProductDetailDTO;
import com.zkthink.ceres.product.entity.Product;
import com.zkthink.ceres.product.entity.Subject;
import com.zkthink.ceres.product.dto.SubjectSaveDTO;
import com.zkthink.ceres.product.dto.SubjectUpdateDTO;
import com.zkthink.ceres.product.dto.SubjectPageDTO;
import com.zkthink.ceres.product.entity.SubjectProduct;
import com.zkthink.ceres.product.service.ProductService;
import com.zkthink.ceres.product.service.SubjectProductService;
import com.zkthink.ceres.product.service.SubjectService;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.zkthink.base.controller.SuperController;
import com.zkthink.base.R;
import com.zkthink.ceres.product.vo.ProductPageVO;
import com.zkthink.context.BaseContextHandler;
import com.zkthink.database.mybatis.conditions.Wraps;
import com.zkthink.dozer.DozerUtils;
import com.zkthink.exception.BizException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import com.zkthink.security.annotation.PreAuth;
import org.springframework.web.bind.annotation.RestController;


/**
 * <p>
 * 前端控制器
 * 专题表
 * </p>
 *
 * @author JustArgo
 * @date 2020-09-11
 */
@Slf4j
@Validated
@AllArgsConstructor
@RestController
@RequestMapping("/subject")
@Api(value = "Subject", tags = "专题表")
@PreAuth(replace = "subject:")
public class SubjectController extends SuperController<SubjectService, Long, Subject, SubjectPageDTO, SubjectSaveDTO, SubjectUpdateDTO> {

    private ProductService productService;

    private SubjectProductService subjectProductService;

    private DozerUtils dozerUtils;

    @ApiOperation("查询专题详细信息")
    @GetMapping("/querySubjectDetail/{subjectId}")
    public R querySubjectDetail(@PathVariable Long subjectId){
        Subject subject = baseService.getById(subjectId);
        SubjectProductDetailDTO subjectProductDetailDTO = dozerUtils.map(subject,SubjectProductDetailDTO.class);
        PageParams<SubjectProduct> pageParams = new PageParams<>();
        pageParams.setModel(SubjectProduct.builder().subjectId(subject.getId()).build());
        pageParams.setCurrent(1);
        pageParams.setSize(50);
        pageParams.setOrder("ascending");
        pageParams.setSort("id");
        BaseContextHandler.setTenant("");
        R<ProductPageVO> productPageVOResult = subjectProductService.querySubjectDetail(pageParams);
        if(productPageVOResult != null){
            subjectProductDetailDTO.setProductVOList(productPageVOResult.getData().getProductVOList());
        }
        return R.success(subjectProductDetailDTO);
    }

    /**
     * Excel导入后的操作
     *
     * @param list
     */
    @Override
    public R<Boolean> handlerImport(List<Map<String, String>> list){
        List<Subject> subjectList = list.stream().map((map) -> {
            Subject subject = Subject.builder().build();
            //TODO 请在这里完成转换
            return subject;
        }).collect(Collectors.toList());

        return R.success(baseService.saveBatch(subjectList));
    }

    @Override
    public R<Subject> save(SubjectSaveDTO model) {
        try{
            List<Long> productIdList = validateProductList(model.getProductIdList());
            Subject subject = dozerUtils.map(model,Subject.class);
            baseService.save(subject);
            Long subjectId = subject.getId();
            for(Long productId:productIdList){
                SubjectProduct subjectProduct = new SubjectProduct().builder().subjectId(subjectId).productId(productId).display(1).build();
                subjectProductService.save(subjectProduct);
            }
            return R.success(subject);
        } catch(BizException e){
            log.error("新增专题失败:"+e.getMessage(),e);
            return R.fail(e);
        } catch(Exception e){
            log.error("新增专题失败:"+e.getMessage(),e);
            return R.fail("新增失败");
        }
    }

    @Override
    public R<Subject> handlerUpdate(SubjectUpdateDTO model) {
        try{
            List<Long> productIdList = validateProductList(model.getProductIdList());
            updateSubjectProductInner(model.getId(),productIdList);
        } catch(BizException e){
            log.error("更新专题失败:"+e.getMessage(),e);
            return R.fail(e);
        } catch(Exception e){
            log.error("更新专题失败:"+e.getMessage(),e);
            return R.fail("更新失败");
        }
        return R.successDef(dozerUtils.map(model,Subject.class));
    }

    @Override
    public R<Boolean> handlerDelete(List<Long> subjectIds) {
        if(!CollectionUtils.isEmpty(subjectIds)){
            for(Long subjectId:subjectIds){
                subjectProductService.remove(Wraps.<SubjectProduct>lbQ().eq(SubjectProduct::getSubjectId,subjectId));
            }
        }
        return R.successDef(true);
    }

    private List<Long> validateProductList(List<String> productIdStrList){
        if(CollectionUtils.isEmpty(productIdStrList)){
            throw new BizException("商品id列表不能为空");
        }
        List<Long> wrongProductIdList = new ArrayList<Long>();
        List<Long> productIdList = new ArrayList<>();
        for(String productIdStr:productIdStrList){
            Long productId = null;
            try{
                productId = Long.valueOf(productIdStr);
            } catch(Exception e){
                log.error(e.getMessage(),e);
                throw new BizException("商品id输入有误");
            }
            Product product = productService.getByIdIgnoreTenant(productId);
            if(product == null || product.getStatus() == YesOrNoEnum.NO.getCode()){
                wrongProductIdList.add(productId);
            } else {
                productIdList.add(productId);
            }
        }
        if(wrongProductIdList.size()>0){
            throw new BizException("以下商品不存在或已下架:"+ StringUtils.join(wrongProductIdList,","));
        }
        return productIdList;
    }

    private void updateSubjectProductInner(Long id, List<Long> productIdList){
        List<SubjectProduct> subjectProductList = subjectProductService.list(Wraps.<SubjectProduct>lbQ().eq(SubjectProduct::getSubjectId,id)
                .eq(SubjectProduct::getIsDelete,YesOrNoEnum.NO.getCode()));
        List<Long> oldProductIdList = subjectProductList.stream().map(o -> o.getProductId()).collect(Collectors.toList());
        List<Long> addProductIdList = new ArrayList<>(productIdList);
        addProductIdList.removeAll(oldProductIdList);

        //新增
        if(addProductIdList.size()>0){
            for(Long productId:addProductIdList){
                SubjectProduct subjectProduct = new SubjectProduct().builder().subjectId(id).productId(productId).display(1).build();
                subjectProductService.save(subjectProduct);
            }
        }

        //删除
        oldProductIdList.removeAll(productIdList);
        if(oldProductIdList.size()>0){
            List<Long> removeSpIds = subjectProductList.stream().filter(o -> oldProductIdList.contains(o.getProductId())).map(o -> o.getId()).collect(Collectors.toList());
            subjectProductService.removeByIds(removeSpIds);
        }
    }

}
